<?php

namespace core;

use core\gateway\AbstractGateway;
use core\execute\method\Method;
use core\execute\method\MethodExecute;
use core\util\String;
class Bootstrap implements Object{

	public static $ACTION = "action";

	private $class;
	private $gatewaySup;
	private $gateway;

	private $httpSession;
	private $action;
	private $methods;

	public function __construct($class) {
		try {
			if(!String::isEmpty($class)){
				$this->class = $class;
				$this->httpSession = HttpSession::getInstance();
				$this->methods = array();

				if($this->httpSession->hasParameter(static::$ACTION) && $this->hasGateway()){
					$this->action = $this->httpSession->getParameter(static::$ACTION);
					$this->continueGateway();
				} else {
					$this->startGateway();
				}
			} else {
				throw new \Exception("Erro: Invalid Class");
			}
		} catch (\Exception $e) {
			var_dump($e);
		}
	}

	private function startGateway() {
		$this->gateway = Bootstrap::createGateway($this->class);

		$this->methods = Method::addMethods(Method::createMethod($this->gateway, AbstractGateway::$ACTION_START, 	 array($this->httpSession), false), $this->methods);
		$this->methods = Method::addMethods(Method::createMethod($this->gateway, AbstractGateway::$PROCESS_PROPERTY, array($this->httpSession), false), $this->methods);
		$this->methods = Method::addMethods(Method::createMethod($this->gateway, AbstractGateway::$ACTION_REQUEST,   array($this->httpSession), false), $this->methods);
		$this->methods = Method::addMethods(Method::createMethod($this->gateway, AbstractGateway::$PROCESS_VIEW, 	 array($this->httpSession), false), $this->methods);

		MethodExecute::executeAll($this->methods);
		$this->updateGateway();
	}

	private function continueGateway(){
		$this->gateway = $this->getGateway();

		$this->methods = Method::addMethods(Method::createMethod($this->gateway, AbstractGateway::$PROCESS_PROPERTY, array($this->httpSession), false), $this->methods);
		$this->methods = Method::addMethods(Method::createMethod($this->gateway, AbstractGateway::$ACTION_REQUEST,   array($this->httpSession), false), $this->methods);

		if(Bootstrap::hasActionGateway($this->gateway, $this->action)){
			$this->methods = Method::addMethods(Method::createMethod($this->gateway, $this->action, array($this->httpSession), false), $this->methods);
		} else {
			throw new \Exception("Erro: Invalid Action");
		}

		$this->methods = Method::addMethods(Method::createMethod($this->gateway, AbstractGateway::$PROCESS_VIEW, array($this->httpSession), false), $this->methods);

		MethodExecute::executeAll($this->methods);
		$this->updateGateway();
	}

	private static function createGateway($class){
		$class = new \ReflectionClass($class);
		return $class->newInstance(null);
	}

	private function hasGateway(){
		if(array_key_exists($this->class, $_SESSION)){
			if(unserialize($_SESSION[$this->class]) instanceof AbstractGateway){
				return true;
			}
		}
		return false;
	}

	private function getGateway(){
		if($this->gateway == null){
			$this->gateway = unserialize($_SESSION[$this->class]);
		}
		return  $this->gateway;
	}

	private function updateGateway(){
		$_SESSION[$this->class] = serialize($this->gateway);
	}

	private static function hasActionGateway(Object $gateway, $method_name){
		$class = new \ReflectionClass($gateway);
		if($class->hasMethod($method_name)){
			return true;
		} else {
			return false;
		}
	}
}
?>